package com.example.sixth.coree.task;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.sixth.coree.utils.SpringUtils;
import com.example.sixth.coree.websocketservice.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.websocket.Session;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class SongTask {
    public static HashMap<String, Long> channelhome = new HashMap();
    private static final Logger logger = LoggerFactory.getLogger(SongTask.class);
    private RedisTemplate redisTemplate = SpringUtils.getBean("redistemp");
    private static ConcurrentHashMap<String, ConcurrentHashMap<String, Session>> chatmap = core.CHATMAP;

    @Scheduled(fixedRate = 30000)
    private void songTask() {
        redisTemplate.boundListOps("history").persist();
        redisTemplate.boundSetOps("ipaddr").persist();
        for (String name : chatmap.keySet()) {
            if (redisTemplate.opsForList().size(name) >= 2) {
                Object index = redisTemplate.opsForList().index(name, 1);
                JSONObject jtp = JSON.parseObject(index.toString());
                Long since = System.currentTimeMillis() / 1000;
                Long second = since % 60, min = since / 60 % 60, hour = (since / 3600 + 8) % 24;
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("time", hour + ":" + min + ":" + second);
                jsonObject.put("type", "preload");
                jsonObject.put("by", "timer");
                jsonObject.put("url", "http://www.gzxtest.xyz:8080/api/song/playurl?mid=" + jtp.getJSONObject("song").get("mid"));
                SendForALL(name, jsonObject.toJSONString());
            }
        }
    }

    private void delsongandsend() {
        long str = System.currentTimeMillis();

        ListOperations listOperations = redisTemplate.opsForList();
        for (String name : chatmap.keySet()) {
            Long size = listOperations.size(name);
            if (size != 0) {//执行检测并删除操作
                JSONObject jsonObject = JSON.parseObject(listOperations.index(name, 0).toString());
                long end = Long.parseLong(jsonObject.get("end").toString());
                if (System.currentTimeMillis() >= end * 1000) {
                    listOperations.leftPop(name);
                    if (size > 1) {
                        JSONObject jnow = JSON.parseObject(listOperations.index(name, 0).toString());
                        jnow.put("type", "playSong");

                        SendForALL(name, jnow.toJSONString());
                        size--;
                    }
                }
            }
            if (size == 0) {
                BoundListOperations history = redisTemplate.boundListOps("history");
                Object index = history.index(RandomUtil.randomLong(0L, history.size()));
                JSONObject jtp = JSON.parseObject(index.toString());
                jtp.put("type", "playSong");
                Long now = System.currentTimeMillis() / 1000;
                jtp.put("since", now);
                jtp.put("end", now + Long.parseLong(jtp.getJSONObject("song").get("length").toString()));
                JSONObject jsonObject = jtp.getJSONObject("user");
                jsonObject.put("user_name", "Robot");
                jsonObject.put("user_id",1);
                jtp.put("user", jsonObject);
                listOperations.rightPush(name, jtp.toJSONString());
                SendForALL(name, jtp.toJSONString());
            }

        }
        logger.info("检查一次用时" + (System.currentTimeMillis() - str) + "ms");

    }

    @Scheduled(fixedRate = 1000)
    void delandsend2() {
        ListOperations listOperations = redisTemplate.opsForList();
        for (String name : chatmap.keySet()) {
            if (channelhome.get(name) == null) {
                channelhome.put(name, System.currentTimeMillis());
            }
            Long len = listOperations.size(name);
            if (len > 0) {
                JSONObject jtp = JSON.parseObject(listOperations.index(name, 0).toString());
                Long songlength = Long.parseLong(jtp.getJSONObject("song").get("length").toString());

                if (System.currentTimeMillis() >= (channelhome.get(name) + songlength * 1000)) {

                    listOperations.leftPop(name);
                    len--;
                    if (len > 0) {
                        JSONObject jnow = JSON.parseObject(listOperations.index(name, 0).toString());
                        channelhome.put(name, System.currentTimeMillis());
                        jnow.put("since", System.currentTimeMillis() / 1000);
                        jnow.put("type", "playSong");
                        SendForALL(name, jnow.toJSONString());
                    }
                }

            }
            if (len == 0) {
                BoundListOperations history = redisTemplate.boundListOps("history");
                Long sz = history.size();
                if (sz != 0) {
                    Object index = history.index(RandomUtil.randomLong(0L, sz));
                    JSONObject jtp = JSON.parseObject(index.toString());
                    jtp.put("type", "playSong");
                    channelhome.put(name, System.currentTimeMillis());
                    jtp.put("since", System.currentTimeMillis() / 1000);
                    JSONObject jsonObject = jtp.getJSONObject("user");
                    jsonObject.put("user_name", "Robot");
                    jsonObject.put("user_id", 1);
                    jtp.put("user", jsonObject);
                    jtp.put("by", "timer");
                    listOperations.rightPush(name, jtp.toJSONString());
                    SendForALL(name, jtp.toJSONString());
                }
            }


        }
    }

    boolean SendForALL(String room_id, String message) {

        ConcurrentHashMap<String, Session> stringSessionConcurrentHashMap = core.CHATMAP.get(room_id);
        for (Session value : stringSessionConcurrentHashMap.values()) {
            try {
                value.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }
}